package at.fhj.mobsecdev.cookit.webrequests;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.provider.Settings.Secure;
import at.fhj.mobsecdev.cookit.R;
import at.fhj.mobsecdev.cookit.model.Recipe;
import at.fhj.mobsecdev.cookit.util.LoadingIndicator;

/**
 * Call web service that returns recipes as a JSON array
 */
public class ViewRecipesAsyncWebCall extends AsyncTask<String, Void, Object> {

	private AddRecipes caller;
	private ProgressDialog dialog;
	private Context context;
	
	public ViewRecipesAsyncWebCall(AddRecipes caller, Activity activity) {
		this.caller = caller;
		this.context = activity;
	}
	
	 protected void onPreExecute() {
	        dialog = new LoadingIndicator(context).createIndicator();
	        dialog.show();
	 }
	
	@Override
	protected Object doInBackground(String... params) {
		StringBuffer jsonResponse = new StringBuffer();
		
		String webServiceUrl = params[0];
		
		try {
			String id = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
			
			List<NameValuePair> getParams = new LinkedList<NameValuePair>();
			getParams.add(new BasicNameValuePair("id", id == null ? "" : id));
			webServiceUrl += "?" + URLEncodedUtils.format(getParams, "utf-8");
			
			HttpClient client = new DefaultHttpClient();
			HttpGet request = new HttpGet(webServiceUrl);
			HttpResponse response = client.execute(request);
				
			String line = "";
			
			/* Read response JSON string */
			BufferedReader rd = new BufferedReader(new InputStreamReader(
					response.getEntity().getContent()));
			while((line = rd.readLine()) != null) {
				jsonResponse.append(line);
			}
		}
		catch(ClientProtocolException e) {
			return new IllegalStateException(context.getResources().getString(R.string.web_service_could_not_connect));
		}
		catch(IOException e) {
			return new IllegalStateException(context.getResources().getString(R.string.web_service_could_not_connect));
		}
		catch(IllegalStateException e) {
			return new IllegalStateException(context.getResources().getString(R.string.web_service_could_not_connect));
		}
		
		JsonParser parser = new JsonParser();
		
		try {
			/* Parse JSON string that contains recipes */
			List<Recipe> parsedRecipes = parser.parseRecipeList(jsonResponse.toString());
			return parsedRecipes;
		} catch (JSONException e) {
			return new IllegalStateException(context.getResources().getString(R.string.web_service_communication_problem));
		}
	}

	@SuppressWarnings("unchecked") //as parser always returns list of recipes
	@Override
	protected void onPostExecute(Object result) {
		super.onPostExecute(result);
		
		if (dialog.isShowing()) {
	        dialog.dismiss();
		}
		if(result instanceof List<?>) // call successful, return recipes
		{
			caller.addRecipes((List<Recipe>)result);
		}
		else if(result instanceof IllegalStateException) //problem at calling web service, show error
		{
			RuntimeException e = (RuntimeException)result;
			caller.webServiceCallFailed(e);
		}
	}
	
	/**
	 * Interface, which specifies the methods that are called after the webservice call. The calls forward either the list of
	 * parsed recipes or error information.
	 */
	public interface AddRecipes
	{
		void addRecipes(List<Recipe> recipes);
		
		void webServiceCallFailed(Exception e);
	}
}
